//
//  SmallDecisionsCommonModalTransition.m
//  SmallDecisions
//
//  Created by 李付雄 on 2025/6/14.
//

#import "SmallDecisionsCommonModalTransition.h"
#import "SmallDecisionsCommonModalInteractiveTransition.h"
#import <YYCategories.h>

@interface SmallDecisionsCommonModalTransition () <UIViewControllerAnimatedTransitioning>

@property (nonatomic, strong) SmallDecisionsCommonModalInteractiveTransition *interactiveTransition;
@property (nonatomic, assign) SmallDecisionsModalType modalType;
@property (nonatomic, strong) UIView *tempView;
@property (nonatomic, assign) BOOL isInteractive;

@end

@implementation SmallDecisionsCommonModalTransition

- (instancetype)init {
    
    self = [super init];
    if (self) {
        
        self.interactiveTransition = [[SmallDecisionsCommonModalInteractiveTransition alloc] init];
        self.time = 0.35;
    }
    return self;
}

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
                                                                            presentingController:(UIViewController *)presenting
                                                                                sourceController:(UIViewController *)source {
    self.modalType = SmallDecisionsModalTypePresent;
    return self;
}

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    
    self.modalType = SmallDecisionsModalTypeDismiss;
    return self;
}

- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    
    if (self.interactiveTransition.isActive) {
        
        self.isInteractive = YES;
        return self.interactiveTransition;
    }
    self.isInteractive = NO;
    return nil;
}

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
    
    return self.time;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    switch (self.modalType) {
            
        case SmallDecisionsModalTypePresent: {
            
            switch (self.animationType) {
                
                case SmallDecisionsAnimationTypeFullPop: {
                    
                    [self popFullPresent: transitionContext];
                } break;
                    
                case SmallDecisionsAnimationTypePop: {
                    
                    [self popPresent: transitionContext];
                } break;
                case SmallDecisionsAnimationTypeAlert: {
                    
                    [self alertPresent: transitionContext];
                } break;
                case SmallDecisionsAnimationTypePicker: {
                    
                    [self pickerPresent:transitionContext];
                } break;
                    
                default:
                    break;
            }
        } break;
            
        case SmallDecisionsModalTypeDismiss: {
            
            switch (self.animationType) {
                
                case SmallDecisionsAnimationTypeFullPop: {
                    
                    [self popFullDismiss: transitionContext];
                } break;
                    
                case SmallDecisionsAnimationTypePop: {
                                   
                    [self popDismiss: transitionContext];
                } break;
                    
                case SmallDecisionsAnimationTypeAlert: {
                    
                    [self alertDismiss:transitionContext];
                } break;
                    
                case SmallDecisionsAnimationTypePicker: {
                    
                    [self pickerDismiss:transitionContext];
                } break;
                    
                default:
                    break;
            }
            
        } break;
            
        default:
            break;
    }
}

- (void)popFullPresent:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width  = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    
    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    tempView.backgroundColor = [UIColor colorWithHexString:@"0x000000"];
    tempView.alpha = 0;
    [containerView addSubview:tempView];
    [self.interactiveTransition addViewController:toVC type:SmallDecisionsAnimationTypePop];

    self.tempView = tempView;
    
    toView.frame = CGRectMake(0, height, width, height);
    [containerView addSubview: toView];
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect: toView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(0, 0)];

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = toView.bounds;
    maskLayer.path  = maskPath.CGPath;
    toView.layer.mask = maskLayer;
        
    UIViewController *vc = toVC;
    if ([toVC isKindOfClass:[UINavigationController class]]) {
        
        vc = [(UINavigationController *)toVC viewControllers].firstObject;
    }
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:5 options: UIViewAnimationOptionCurveLinear animations:^{
        
        toView.top = 0;
        tempView.alpha = 0.5;
        
    } completion:^(BOOL finished) {
       
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)popPresent:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width  = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    
    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    tempView.backgroundColor = [UIColor colorWithHexString:@"0x000000"];
    tempView.alpha = 0;
    [containerView addSubview:tempView];
    
    [self.interactiveTransition addViewController:toVC type:SmallDecisionsAnimationTypePop];

    self.tempView = tempView;
    
    toView.frame = CGRectMake(0, height, width, height / 2.0);
    [containerView addSubview: toView];
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect: toView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)];

    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = toView.bounds;
    maskLayer.path  = maskPath.CGPath;
    toView.layer.mask = maskLayer;
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    
    UIViewController *vc = toVC;
    if ([toVC isKindOfClass:[UINavigationController class]]) {
        
        vc = [(UINavigationController *)toVC viewControllers].firstObject;
    }
    
    [UIView animateWithDuration:time animations:^{
       
        toView.bottom  = height;
        tempView.alpha = 0.5;
    } completion:^(BOOL finished) {
        
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)alertPresent:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    toView.frame = CGRectMake(0, -containerView.height, containerView.width, containerView.height);
    toView.backgroundColor = [UIColor clearColor];
    toView.alpha = 0.0;
    [containerView addSubview: toView];
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    
    [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:1.5 options: UIViewAnimationOptionCurveLinear animations:^{
        
        toView.alpha = 1;
        toView.top   = 0;
    } completion:^(BOOL finished) {
       
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)popFullDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    NSTimeInterval time = [self transitionDuration: transitionContext];
    if (self.isInteractive) {
        
        [UIView animateWithDuration:time delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            
            fromView.left = width;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    } else {
        
        [UIView animateWithDuration:time animations:^{
            
            fromView.top = height;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    }
}

- (void)popDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    NSTimeInterval time = [self transitionDuration: transitionContext];
    if (self.isInteractive) {
        
        [UIView animateWithDuration:time animations:^{
            
            fromView.left = width;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    } else {
        
        [UIView animateWithDuration:time animations:^{
            
            fromView.top = height;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    }
}

- (void)alertDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:5 options: UIViewAnimationOptionCurveLinear animations:^{
       
        fromView.alpha = 0;
        fromView.top = containerView.height / 2.0;
    } completion:^(BOOL finished) {
        
        if (![transitionContext transitionWasCancelled]) {
            
            [fromView removeFromSuperview];
        }
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)pickerPresent:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width  = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    
    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    tempView.backgroundColor = [UIColor colorWithHexString:@"0x000000"];
    tempView.alpha = 0;
    [containerView addSubview:tempView];
    
    [self.interactiveTransition addViewController:toVC type:SmallDecisionsAnimationTypePop];

    self.tempView = tempView;
    
    toView.frame = CGRectMake(10, height, width - 20, self.showHeight ? self.showHeight : height * 0.35);
    toView.layer.cornerRadius = 10;
    toView.layer.masksToBounds = YES;
    toView.layer.shadowColor = [UIColor colorWithHexString:@"0xC8C8C8"].CGColor;
    toView.layer.shadowRadius = 10;
    toView.layer.shadowOffset = CGSizeMake(0, 0);
    toView.layer.shadowOpacity = 0.5;
    [containerView addSubview: toView];
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    UIViewController *vc = toVC;
    if ([toVC isKindOfClass:[UINavigationController class]]) {
        
        vc = [(UINavigationController *)toVC viewControllers].firstObject;
    }
    
    [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:5 options: UIViewAnimationOptionCurveLinear animations:^{
        
        toView.bottom  = height - 10;
        tempView.alpha = 0.5;
    } completion:^(BOOL finished) {
       
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)pickerDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    NSTimeInterval time = [self transitionDuration: transitionContext];
    if (self.isInteractive) {
        
        [UIView animateWithDuration:time delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            
            fromView.left = width;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    } else {
        
        [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.85 initialSpringVelocity:10 options: UIViewAnimationOptionCurveLinear animations:^{
            
            fromView.top = height;
            self.tempView.alpha = 0;
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    }
}

- (void)publishActivityPresent:(id <UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width  = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    
    UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    tempView.backgroundColor = [UIColor colorWithHexString:@"0x000000"];
    tempView.alpha = 0;
    [containerView addSubview:tempView];
    
    [self.interactiveTransition addViewController:toVC type:SmallDecisionsAnimationTypePop];
    self.tempView = tempView;
    
    toView.frame = CGRectMake(0, height, width, 550);
    [containerView addSubview: toView];
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect: toView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(10, 10)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = toView.bounds;
    maskLayer.path  = maskPath.CGPath;
    toView.layer.mask = maskLayer;
    
    NSTimeInterval time = [self transitionDuration: transitionContext];
    UIViewController *vc = toVC;
    if ([toVC isKindOfClass:[UINavigationController class]]) {
        
        vc = [(UINavigationController *)toVC viewControllers].firstObject;
    }
    
    [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.75 initialSpringVelocity:5 options: UIViewAnimationOptionCurveLinear animations:^{
        
        toView.bottom  = height;
        tempView.alpha = 0.5;
    } completion:^(BOOL finished) {
       
        [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
}

- (void)publishActivityDismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIView *containerView    = [transitionContext containerView];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView *fromView = fromVC.view;
    UIView *toView   = toVC.view;
    if (!containerView || !fromView || !toView) {
        
        return;
    }
    
    CGFloat width = CGRectGetWidth(containerView.frame);
    CGFloat height = CGRectGetHeight(containerView.frame);
    NSTimeInterval time = [self transitionDuration: transitionContext];
    if (self.isInteractive) {
        
        [UIView animateWithDuration:time delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            
            fromView.left = width;
            self.tempView.alpha = 0;
            
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    } else {
        
        [UIView animateWithDuration:time delay:0 usingSpringWithDamping:0.85 initialSpringVelocity:10 options: UIViewAnimationOptionCurveLinear animations:^{
            
            fromView.top = height;
            self.tempView.alpha = 0;
        } completion:^(BOOL finished) {
            
            if (![transitionContext transitionWasCancelled]) {
                
                [self.tempView removeFromSuperview];
                [fromView removeFromSuperview];
            }
            [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
        }];
    }
}



@end
